import tkinter as tk
import threading
from tkinter import filedialog
from tkinter.filedialog import askdirectory
from tkinter.scrolledtext import ScrolledText


from win32com.client import Dispatch
import pdfplumber
import docx
import os
import openpyxl as xl

class Application(tk.Frame):
    def __init__(self, master=None):
        super().__init__(master)
        self.master = master
        self.pack()
        self.create_widgets()

    def create_widgets(self):

        self.frame_top = tk.Frame(self)
        self.btn_open_file = tk.Button(self.frame_top)
        self.btn_open_file["text"] = "选择pdf/doc/docx文件\n并生成xlsx文件"
        self.btn_open_file["command"] =lambda :self.thread_it(self.openFile)
        self.btn_open_file.pack(side="left", padx=0, pady=2)

        self.btn_open_path = tk.Button(self.frame_top)
        self.btn_open_path["text"] = "选择路径下所有的pdf/doc/docx文件\n并生成xlsx文件"
        self.btn_open_path["command"] = lambda :self.thread_it(self.openPath)
        self.btn_open_path.pack(side="left", padx=0, pady=2)

        self.btn_clear = tk.Button(self.frame_top, text="清屏", 
                              command=self.clear_text)
        self.btn_clear.pack(side="left", padx=0, pady=2)

        self.btn_quit = tk.Button(self.frame_top, text="退出", fg="red",
                              command=self.master.destroy)
        self.btn_quit.pack(side="left", padx=0, pady=2)


        self.frame_top.pack(side="top", fill="both")
        self.text_options = {"state": "disabled",
                             "bg": "black",
                             "fg": "#08c614",
                             "insertbackground": "#08c614",
                             "selectbackground": "#f01c1c"}

        self.text = ScrolledText(self, **self.text_options)

        # It seems not to work when Text is disabled...
        # self.text.bind("<<Modified>>", lambda: self.text.frame.see(tk.END))

        self.text.pack(expand=True, fill="both")



    def openFile(self):
        fileName =filedialog.askopenfilename(filetypes=[("PDF",".pdf"),("DOC",".doc"),("DOCX",".docx")])
        if fileName !='':
            s=self.readFile(fileName)
            self.write_excel_file(s)
        
    def readFile(self,f):
        self.show(f)
        s=[]
        if f.split('.')[-1]=='pdf':
            s=self.readPdf(f)
        elif f.split('.')[-1]=='docx':
            s=self.readWord(f)
        elif f.split('.')[-1]=='doc':
            newF=self.doc2docx(f)
            s=self.readWord(newF)
        return s
   
    def openPath(self):
        path=askdirectory()
        if path != '':
            # files= os.listdir(path) #得到文件夹下的所有文件名称
            # s = []
            # for file in files: #遍历文件夹
            #     if not os.path.isdir(file): #判断是否是文件夹，不是文件夹才打开
            #         s.append(self.readFile(os.path.join(path,file))) #每个文件的文本存到list中
            # print(s) #打印结果
            # self.write_excel_file(s,path.split("/")[-1])
            s=self.traversal(path)
            print(len(s))
            self.write_excel_file(s)


             
    def traversal(self,path):
        s=[]
        # 遍历目录下所有的文件和文件夹
        files= os.listdir(path) #得到文件夹下的所有文件名称
        for file in files: #遍历文件夹
            if os.path.isfile(os.path.join(path,file)): #判断是否是文件夹，不是文件夹才打开
                # 判断是否是doc,docx,pdf
                if file.split('.')[-1]=='pdf' or file.split('.')[-1]=='doc' or file.split('.')[-1]=='docx':
                    s.append(self.readFile(os.path.join(path,file))) #每个文件的文本存到list中
            else:
                s1=self.traversal(os.path.join(path,file))
                s.extend(s1)
        return s

    def readPdf(self,f):
        with pdfplumber.open(f) as pdf:
            # page_count = len(pdf.pages)
            # print('页总数',page_count)  # 得到页数
            context=[]
            for page in pdf.pages:
                # print('---------- 第[%d]页 ----------' % page.page_number)
                # # 获取当前页面的全部文本信息，包括表格中的文字
                # print(page.extract_text().split('\n')[:-1])
                # context.extend(page.extract_text().split('\n')[:-1])
                try:
                    context.extend(page.extract_text().strip().split('\n'))
                except Exception as e:
                    print(e)
                    self.show('获取该pdf文本内容失败，该pdf可能为图片')
            return [f,"".join(context)]

    def readWord(self,f):
        file=docx.Document(f)
        paras=[]
        # print("段落数:"+str(len(file.paragraphs)))#每个回车隔离一段

        #输出每一段的内容
        for para in file.paragraphs:
            # print(para.text)
            paras.extend(para.text.strip())

        #输出段落编号及段落内容
        # for i in range(len(file.paragraphs)):
        #     print("第"+str(i)+"段的内容是："+file.paragraphs[i].text)
        return [f,''.join(paras)]

# doc转docx
    def doc2docx(self,path):
        w = Dispatch('Word.Application')
        w.Visible = 0
        w.DisplayAlerts = 0
        doc = w.Documents.Open(path)
        newpath = os.path.splitext(path)[0] + '.docx'
        doc.SaveAs(newpath, 12, False, "", True, "", False, False, False, False)
        doc.Close()
        w.Quit()
        os.remove(path)
        return newpath

# wps转docx
    def wps2docx(self,path):
        w = Dispatch('Kwps.Application')
        w.Visible = 0
        w.DisplayAlerts = 0
        doc = w.Documents.Open(path)
        newpath = os.path.splitext(path)[0] + '.docx'
        doc.SaveAs(newpath, 12, False, "", True, "", False, False, False, False)
        doc.Close()
        w.Quit()
        os.remove(path)
        return newpath

    def write_excel_file(self,s):
        filename1 = filedialog.asksaveasfilename(filetypes=[("XLSX",".xlsx")])

        self.show('* 开始写入excel文件 ' + filename1 + ' * \n')
        if os.path.exists(filename1):
            workbook = xl.load_workbook(filename1)
        else:
            self.show('* excel不存在，创建excel ' + filename1 + ' 成功* \n')
            workbook = xl.Workbook()
            workbook.save(filename1+'.xlsx')
        sheet = workbook.active
        headers = ['文件路径',"内容","目录"]
        sheet.append(headers)
        if len(s)==2:
            # 单个文件情况
            # print('print lenth of s '+str(len(s)))
            # print('print s1 '+s[0])
            # print('print s2 '+s[1])
            sheet.append([s[0].split("\\")[-1],s[1],'当前目录'])
        else:
            #多个文件情况
            for c in s:
                # print('print lenth of c '+str(len(c)))
                # print('c='+c)
                sheet.append([c[0].split("\\")[-1],c[1],c[0].split("\\")[-2]])
        workbook.save(filename1+'.xlsx')
        # self.show('***** 生成Excel文件 ' + filename1 + ' ***** \n')
    
    def clear_text(self):
        """Clears the Text widget"""
        self.text.config(state="normal")
        self.text.delete(1.0, "end-1c")
        self.text.config(state="disabled")
    
    def show(self, message):
        """Inserts message into the Text wiget"""
        self.text.config(state="normal")
        self.text.insert("end", message)
        self.text.insert("end", '\n')
        self.text.see("end")
        self.text.config(state="disabled")
    
    def thread_it(self,func, *args):
        # 创建
        t = threading.Thread(target=func, args=args) 
        # 守护 !!!
        t.daemon=True
        # 启动
        t.start()
        # 阻塞--卡死界面！
        # t.join()


root = tk.Tk()
app = Application(master=root)
app.pack(expand=True,fill='both')
app.master.title("F2X")
# app.master.geometry('400x200+10+10')
# 获取屏幕 宽、高
w=500
h=500
ws = root.winfo_screenwidth()
hs = root.winfo_screenheight()
# 计算 x, y 位置
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
app.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
app.mainloop()